﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rhino.DSL;
using System.Reflection;
using Boo.Lang.Compiler;
using NLog;

namespace NGinnBPM.Services.Scripting.BooScript
{
    internal class ProcessScriptDslEngine : DslEngine
    {
        private static Logger log = LogManager.GetCurrentClassLogger();
        private Func<string, string> _canonize = null;

        public ProcessScriptDslEngine(Func<string, string> canonize)  
        {
            this.Storage = new SimpleFSStorage();
            _canonize = canonize;
        }

        public override string CanonizeUrl(string url)
        {
            if (_canonize != null) return _canonize(url);
            return base.CanonizeUrl(url);
        }

        protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls)
        {
            
            List<Assembly> asmss = new List<Assembly>();
            if (AutoReferenceLoadedAssemblies)
                asmss.AddRange(AppDomain.CurrentDomain.GetAssemblies());
            asmss.AddRange(ReferencedAssemblies);
            asmss.Add(typeof(NGinnBPM.Lib.Data.DataUtil).Assembly);
            asmss.Add(typeof(ProcessScriptDslEngine).Assembly);
            foreach (Assembly asm in asmss)
            {
                try
                {
                    string loc = asm.Location;
                    if (!compiler.Parameters.References.Contains(asm)) compiler.Parameters.References.Add(asm);
                }
                catch (Exception) { log.Debug("Error adding assembly dependency: {0}", asm.FullName); }
            }
            compiler.Parameters.Ducky = true;
            compiler.Parameters.WhiteSpaceAgnostic = true;
            
            for (int i = 0; i < pipeline.Count; i++)
            {
                
            }
            pipeline.Replace(typeof(Boo.Lang.Parser.BooParsingStep), new Boo.Lang.Parser.WSABooParsingStep());
            //pipeline.Replace(typeof(Boo.Lang.Compiler.Steps.
            //pipeline.Insert(1, new AutoReferenceFilesCompilerStep());
        }

        private List<Assembly> _references = new List<Assembly>();
        public IList<Assembly> ReferencedAssemblies
        {
            get 
            {
                return _references;
            }
        }

        private bool _autoReference = false;
        public bool AutoReferenceLoadedAssemblies
        {
            get { return _autoReference; }
            set { _autoReference = value; }
        }
    
    }
}
